//    Copyright (C) Kherty.  All rights reserved.
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Windows;
using System.Windows.Documents;
using OpenLS.Core.Serialization;

namespace OpenLS.Drawing
{
    /// <summary>
    /// Represents a paragraph in a TextBody
    /// </summary>
    public class TextParagraph : IOfficeXmlSerializable
    {
        private TextCharacterProperties _endParaRPr;
        private TextParagraphProperties _rPr;
        private readonly List<RunBase> _runs = new List<RunBase>();

        ///<summary>
        /// Initializes a new empty paragraph.
        ///</summary>
        public TextParagraph()
        {
        }

        ///<summary>
        /// Initializes a new paragraph with text as content.
        ///</summary>
        ///<param name="text">The text in the new paragraph</param>
        public TextParagraph(string text)
        {
            Contract.Requires(text != null);
            Runs.Add(new RegularTextRun(text));
        }

        public TextCharacterProperties EndProperties
        {
            get { return _endParaRPr; }
            set { _endParaRPr = value; }
        }

        public TextParagraphProperties TextParagraphProperties
        {
            get { return _rPr; }
            set { _rPr = value; }
        }


        public List<RunBase> Runs
        {
            get { return _runs; }
        }

        internal Paragraph Paragraph
        {
            get
            {
                Paragraph result = new Paragraph();
                result.Margin = new Thickness();
                //\\  result.FontSize = 18 * 4 / 3;
                if (TextParagraphProperties != null)
                {
                    foreach (Setter setter in TextParagraphProperties.GetAllSetters())
                        result.SetValue(setter.Property, setter.Value);
                }
                foreach (RunBase r in Runs)
                    result.Inlines.Add(r.Inline);
                return result;
            }
        }

        internal static TextParagraph FromParagraph (Paragraph paragraph)
        {
            TextParagraph result = new TextParagraph();
            foreach (var inline in paragraph.Inlines)
            {
                result.Runs.Add(RunBase.FromInline (inline));
            }
            result.TextParagraphProperties = new TextParagraphProperties();
            switch (paragraph.TextAlignment)
            {
                case TextAlignment.Center:
                    result.TextParagraphProperties.Alignment = TextAlignType.Center;
                    break;
                case TextAlignment.Left:
                    result.TextParagraphProperties.Alignment = TextAlignType.Left;
                    break;
                case TextAlignment.Right:
                    result.TextParagraphProperties.Alignment = TextAlignType.Right;
                    break;
                case TextAlignment.Justify:
                    result.TextParagraphProperties.Alignment = TextAlignType.Justified;
                    break;
            }

            return result;
        }

        #region IOfficeXmlSerializable Members

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            //\\ XmlReader _reader = context.Reader;
            using (var c = context.Read("p"))
            {
                TextParagraphProperties = c.ReadOptionalElementAs<TextParagraphProperties>("pPr");
                RunBase run = ReadTextRun(c);
                while (run != null)
                {
                    Runs.Add(run);
                    run = ReadTextRun(c);
                }
                EndProperties = c.ReadOptionalElementAs<TextCharacterProperties>("endParaRPr");
            }
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            using (WriteContext c = context.Write("p"))
            {
                c.WriteOptionalElementAs(TextParagraphProperties, "pPr");
                foreach (RunBase r in Runs)
                    c.WriteElement(r);
                c.WriteOptionalElementAs(EndProperties, "endParaRPr");
            }
        }

        #endregion

        private static RunBase ReadTextRun(ReadContext c)
        {
            switch (c.ReaderLocalName)
            {
                case "r":
                    RegularTextRun r = new RegularTextRun();
                    r.ReadXmlCore(c);
                    return r;
                case "br":
                    TextLineBreak lb = new TextLineBreak();
                    lb.ReadXmlCore(c);
                    return lb;
                case "fld":
                    TextField f = new TextField();
                    f.ReadXmlCore(c);
                    return f;
                default:
                    return null;
            }
        }
    }
}